#!/usr/bin/perl

package Swignition::Export;
require Exporter;
@ISA       = qw(Exporter);
@EXPORT    = qw(allOf allOfLiteral allOfObj firstOf firstOfLiteral inProp findSubject);

sub firstOf
{
	my $subject  = shift;
	return unless ($subject && (ref $subject eq 'Swignition::RDFModel::Subject'));
	foreach my $p (@_)
	{
		return $subject->firstVal($p)->toString
			if ($subject->property($p));
	}
	return;
}

sub firstOfLiteral
{
	my $subject     = shift;
	my $props       = shift;
	my $secondLevel = shift || $props;
	my $recursive   = shift || 4;
	
	return unless ($subject);

	foreach my $p (@$props)
	{
		$P = $subject->property($p);
		next unless ($P);
		
		foreach my $V (@{ $P->valObjects })
		{
			return $V->toString
				unless ($V->type);
			
			my $x;
			my $newSubject = findSubject($subject->{page}->{RDF}, $V->toString);
			if ($newSubject)
			{
				if ($recursive)
					{ $x = firstOfLiteral($newSubject, $secondLevel, $secondLevel, $recursive-1); }
				else
					{ $x = firstOf($newSubject, @$props); }
			}
			
			return $x if (defined $x);
		}
	}
	
	return firstOf($subject, @$props);
}

sub allOf
{
	my $subject  = shift;
	return unless ($subject && (ref $subject eq 'Swignition::RDFModel::Subject'));
	my %rv;
	foreach my $p (@_)
	{
		next unless (defined $subject->property($p));
		foreach my $v ( @{$subject->property($p)->valObjects} )
		{
			$rv{ $v->toString } = 1;
		}
	}
	return (keys %rv);
}

sub allOfSimple
{
	my $subject  = shift;
	return unless ($subject && (ref $subject eq 'Swignition::RDFModel::Subject'));
	my %rv;
	foreach my $p (@_)
	{
		next unless (defined $subject->propertySimple($p));
		foreach my $v ( @{$subject->propertySimple($p)->valObjects} )
		{
			$rv{ $v->toString } = 1;
		}
	}
	return (keys %rv);
}

sub allOfLiteral
{
	my $subject     = shift;
	my $props       = shift;
	my $secondLevel = shift || $props;
	my $recursive   = shift || 4;
	my %rv;
	
	foreach my $p (@$props)
	{
		$P = $subject->property($p);
		next unless ($P);
		
		foreach my $V (@{ $P->valObjects })
		{
			unless ($V->type)
			{
				$rv{ $V->toString } = 1;
				next;
			}
			
			my @x;
			my $newSubject = findSubject($subject->{page}->{RDF}, $V->toString);
			if ($newSubject)
			{
				if ($recursive)
					{ @x = allOfLiteral($newSubject, $secondLevel, $secondLevel, $recursive-1); }
				else
					{ @x = allOf($newSubject, @$props); }
			}
			
			foreach my $x (@x)
				{ $rv{$x} = 1; }
		}
	}
	
	return (keys %rv) if (%rv);
	return allOf($subject, @$props);
}

sub allOfObj
{
	my $subject  = shift;
	return unless ($subject);
	my @rv;
	foreach my $p (@_)
	{
		next unless (defined $subject->property($p));
		foreach my $v ( @{$subject->property($p)->valObjects} )
		{
			push @rv, $v;
		}
	}
	return @rv;
}

sub inProp
{
	my $subject  = shift;
	return unless ($subject);
	my $look_for = shift;
	foreach my $p (@_)
	{
		next unless $subject->property($p);
		foreach my $v (@{$subject->property($p)->valObjects})
		{
			if ($v->toString eq $look_for)
			{
				return $look_for;
			}
		}
	}
	return;
}

sub findSubject
{
	my $triples = shift;
	my $url     = shift;
	
	return $triples->{$url}
		if ($triples->{$url} && (ref $triples->{$url} eq 'Swignition::RDFModel::Subject'));
	return
		unless ($url =~ /^[a-z0-9]+\:/i);
		
	foreach my $s (keys %{$triples})
	{
		my $S = $triples->{$s};
		my @v = allOfSimple($S, 'http://www.w3.org/2006/link#uri');
		foreach my $v (@v)
			{ return $triples->{$s} if ($v eq $url); }
	}
		
	return;
}

1;
